package com.coocaa.ops.common.core.base.util;


import com.coocaa.ops.common.core.base.entity.BaseHistoryTableEntity;
import com.coocaa.ops.common.core.base.entity.BaseOriginTableEntity;
import com.coocaa.ops.common.tool.base.InstanceUtil;
import com.coocaa.ops.common.tool.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author bijiahao
 * @date : 2018/6/1.
 * @description: 实体类复制工具
 *
 */
public class BeanCopyUtil {

    public static <TH extends BaseHistoryTableEntity> TH copyOrigin2History(BaseOriginTableEntity originTableEntity, Integer userId, TH historyEntity) {
        copyOrig2Target(originTableEntity, historyEntity, "原始表实体类复制->历史表实体类");
        historyEntity.setModifier(userId);
        return historyEntity;
    }

    public static <TO extends BaseOriginTableEntity> TO copyHistory2Origin(BaseHistoryTableEntity historyEntity, Integer userId, TO originEntity) {
        copyOrig2Target(historyEntity, originEntity, "历史表实体类复制->原始表实体类");
        return originEntity;
    }

    /**
     * @param origin
     * @param target
     * @param errBizDesc
     */
    public static void copyOrig2Target(Object origin, Object target,  String errBizDesc) throws BusinessException {
        try {
            BeanUtils.copyProperties(origin, target);
        } catch (Exception e) {
            Map<String, Object> errMap = InstanceUtil.newHashMap(1);
            errMap.put("errBizDesc", errBizDesc);
            throw new BusinessException(errMap, e.getMessage());
        }
    }

    public static void copyOrig2TargetWithNullCheck(Object origin, Object target,  String errBizDesc) throws BusinessException {
        try {
            BeanUtils.copyProperties(origin, target, getNullPropertiesName(origin));
        } catch (Exception e) {
            Map<String, Object> errMap = InstanceUtil.newHashMap(1);
            errMap.put("errBizDesc", errBizDesc);
            throw new BusinessException(errMap, e.getMessage());
        }
    }

    private static String[] getNullPropertiesName(Object origin) {
        final BeanWrapper src = new BeanWrapperImpl(origin);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
}
